#ifndef __COMPONENT_EAT_PICKABLE_BEHAVIOR_H__
#define __COMPONENT_EAT_PICKABLE_BEHAVIOR_H__

#include <set>
#include "ComponentBehavior.hpp"
#include "Engine/MathUtils.hpp"
#include "Engine/Vector2.hpp"

#include "EasyMachine.hpp"
#include "GameLock.hpp"
#include "GameEnum.h"

using namespace PocketSurvival::Engine;

namespace PocketSurvival
{

    struct ComponentEatPickableBehavior;
    struct ComponentCreature;
    struct ComponentPathfinding;
    class SubsystemTimeOfDay;
    class SubsystemPickables;
    class Pickable;

    struct ComponentEatPickableBehavior : public ComponentBehavior
    {
    protected:
        enum class MachineState
        {
            Inactive,           // 不活跃的
            Move,
            PickableMoved,
            Eat,
        };

        class StateMachine : public EasyMachine<MachineState>
        {
        private:
            ComponentEatPickableBehavior * m_eatPickable;
        public:
            StateMachine(ComponentEatPickableBehavior *eatPickableBehavior);

            virtual void enter() override;
            virtual void update(float dt) override;
            virtual void leave() override;
        };

    protected:
        bool m_feed;
        Pickable *m_pickable = nullptr;
        double m_nextFindPickableTime = 0;
        double m_nextPickablesUpdateTime = 0;
        double m_eatTime = 0;

        float m_satiation = 0.0f;                  // 饱食度
        float m_blockedTime = 0.0f;
        int32_t m_blockedCount;
        float m_foodFactors[10] = { 0.0f };

        float m_importanceLevel = 1.0f;
        StateMachine *m_stateMachine;

        std::set<Pickable *> m_pickableSet;
        SpinLock m_pickablSetLock;

    protected:
        Pickable *findPickable(const Vector3 &position);
        bool tryAddPickable(Pickable *pickable);

    public:
        ComponentCreature *componentCreature;
        ComponentPathfinding *componentPathfinding;

        SubsystemTimeOfDay *subsystemTimeOfDay;
        SubsystemPickables *subsystemPickables;

        ComponentEatPickableBehavior() = default;
        ~ComponentEatPickableBehavior();

        bool getIsFeed();
        void setIsFeed(bool feed);

        virtual float getImportanceLevel() override;


        virtual void update(float dt) override;
        virtual void load(const nlohmann::json &jsonData) override;
        virtual const std::string &getName() const override;
        static const std::string &GetName();        
    };
}

#endif
